#ifndef _grammar_
#define _grammar_

#include <list>
#include <set>
#include <vector>
#include <fstream>
#define N 50

using namespace std;

//定义文法类，保存文法个数和记录所有文法
class Grammar
{
public:
    list<char> grammarTable[N][N];
    char terminalChar[N];
    int terNum;
    int terminum;
    int UnterNum;
    int countEachRow[N];
    int count;
    string Untermial[N];
    string termial[N];

    Grammar()
    {
        terNum = 0;
        terminum = 0;
        UnterNum = 0;
    }
};
//保存每个非终结符的FIRST集合
class FIRST
{
public:
    //保存每个非终结符的FIRST集合
    set<char> First[N];
    //保存非终结符
    char nonTerminal[N];
    //保存是否计算出相应的FIRST集
    bool flag[N] = {0};
    //保存已计算FIRST集的个数
    int calCount;

    FIRST()
    {
        calCount = 0;
    }
};
class Position
{
public:
    int x;
    int y;
    Position()
    {
        x = -1;
        y = -1;
    }
};
//保存每个非终结符的FOLLOW集合
class FOLLOW
{
public:
    //保存每个非终结符的FOLLOW集合
    set<char> Follow[N];
    //保存非终结符
    char nonTerminal[N];
    //保存是否计算出相应的FOLLOW集
    bool flag[N] = {0};
    //保存已计算Follow集的个数
    int calCount;
    //保存产生式的索引
    vector<Position> position[N];

    FOLLOW()
    {
        calCount = 0;
    }
};

const int maxn = 100 + 5;
char buf[maxn]; //输入产生式
int n;          //产生式的数量
class node
{
public:
    string left;       //产生式左部
    set<string> right; //产生式右部

    node(const string &str)
    {
        left = str;

        right.clear();
    }
    void push(const string &str)
    {
        right.insert(str);
    }
    void print()
    {
        printf("%s->", left.c_str());
        set<string>::iterator it = right.begin();
        printf("%s", it->c_str());
        it++;
        for (; it != right.end(); it++)
            printf("|%s", it->c_str());
        cout << endl;
    }
    void printtf(ofstream &out)
    {

        out << left.c_str() << "->";
        set<string>::iterator it = right.begin();
        out << it->c_str();
        it++;
        for (; it != right.end(); it++)
        {
            out << "|" << it->c_str();
        }
        out << endl;
    }
};

#endif // _grammar_